package bll

import (
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/util"
	"sync"
	"time"

	"github.com/LyricTian/rand"
	"github.com/pkg/errors"
)

// AuthCode 企业管理
type AuthCode struct {
	AuthCodeModel model.IAuthCode `inject:"IAuthCode"`
	UserModel     model.IUser     `inject:"IUser"`
	AuthUserModel model.IAuthUser `inject:"IAuthUser"`
	sync.RWMutex
}

// QueryPage 查询分页数据
func (a *AuthCode) QueryPage(params schema.AuthCodeQueryParam, pageIndex, pageSize uint) (int64, []*schema.AuthCodeQueryResult, error) {
	return a.AuthCodeModel.QueryPage(params, pageIndex, pageSize)
}

// QueryHistoryPage 查询历史分页数据
func (a *AuthCode) QueryHistoryPage(params schema.AuthHistoryQueryParam, pageIndex, pageSize uint) (int64, []*schema.AuthHistoryQueryResult, error) {
	total, items, err := a.AuthCodeModel.QueryHistoryPage(params, pageIndex, pageSize)
	if err != nil {
		return 0, nil, err
	}

	for i, item := range items {
		uitem, _ := a.UserModel.Get(item.UserID)
		if uitem != nil {
			items[i].Nickname = uitem.Nickname
			items[i].Gender = uitem.Gender
		}

		if len(item.AuthUsers) > 0 {
			items[i].Tel = item.AuthUsers[0].Tel
		}
	}

	return total, items, nil
}

// Get 精确查询数据
func (a *AuthCode) Get(recordID string) (*schema.AuthCode, error) {
	return a.AuthCodeModel.Get(recordID)
}

// 获取验证码
func (a *AuthCode) getCode() (string, error) {
	for {
		code := rand.MustRandom(6, rand.LdigitAndUpperCase)
		exists, err := a.AuthCodeModel.CheckCode(code)
		if err != nil {
			return "", errors.Wrapf(err, "获取验证码发生错误")
		} else if exists {
			continue
		}
		return code, nil
	}
}

// Create 创建数据
func (a *AuthCode) Create(item *schema.AuthCode) error {
	a.Lock()
	defer a.Unlock()

	code, err := a.getCode()
	if err != nil {
		return err
	}

	item.Status = 1
	item.Code = code
	item.ID = 0
	item.RecordID = util.UUID()
	item.Created = time.Now().Unix()
	item.Deleted = 0
	return a.AuthCodeModel.Create(item)
}

// UpdateStatus 更新状态
func (a *AuthCode) UpdateStatus(recordID string, status int) error {
	info := map[string]interface{}{
		"status": status,
	}
	return a.AuthCodeModel.Update(recordID, info)
}

// Delete 删除数据
func (a *AuthCode) Delete(recordID string) error {
	return a.AuthCodeModel.Delete(recordID)
}

// Check 检查认证码
func (a *AuthCode) Check(code string) (*schema.AuthCode, error) {
	item, err := a.AuthCodeModel.GetByCode(code)
	if err != nil {
		return nil, err
	} else if item == nil {
		return nil, errors.New("无效的认证码")
	} else if item.Status == 2 {
		return nil, errors.New("无效的认证码")
	}

	if valid := a.Verify(item); !valid {
		return nil, errors.New("认证码已失效")
	}

	return item, nil
}

// Verify 验证认证码
func (a *AuthCode) Verify(item *schema.AuthCode) bool {
	if item.EffectiveMode == 1 {
		start, end := time.Unix(item.EffectiveStart, 0), time.Unix(item.EffectiveEnd, 0)
		now := time.Now()
		if now.Before(start) || now.After(end) {
			return false
		}
	} else if item.EffectiveMode == 2 {
		if item.EffectiveNumber <= item.UsedNumber {
			return false
		}
	}

	return true
}

// CreateHistory 创建数据
func (a *AuthCode) CreateHistory(item *schema.AuthHistory) error {
	item.ID = 0
	item.Created = time.Now().Unix()
	item.Deleted = 0
	return a.AuthCodeModel.CreateHistory(item)
}

// IncUsedNumber 递增使用次数
func (a *AuthCode) IncUsedNumber(recordID string) error {
	return a.AuthCodeModel.IncUsedNumber(recordID)
}
